#pragma once

#include <string>
#include <stack>
#include <memory>
#include <functional>
#include <shared_mutex>

namespace rtbus {
class RtCommuItf;
}  // namespace rtbus

namespace rtdev {
class SafetyBoardItf;
constexpr void setBit(uint8_t* buf, size_t bit) { buf[bit / 8] |= (1 << (bit % 8)); }
constexpr void clrBit(uint8_t* buf, size_t bit) { buf[bit / 8] &= ~(1 << (bit % 8)); }
constexpr bool getBit(uint8_t* buf, size_t bit) { return (buf[bit / 8] >> (bit % 8)) & 1; }

enum RtDevState
{
    RtDevStateOffline = 0,
    RtDevStateInit,
    RtDevStateRu
};

enum RtDevType
{
    DEV_BP_HANDLE = 0,
    DEV_SAFETY_BOARD = 1,
    DEV_TIO = 2,
    DEV_TIO_SENSOR = 10,
    DEV_ROBOT = 100,
};
class RtDevItf
{
public:
    virtual ~RtDevItf() = default;

    virtual int boot() = 0;
    virtual int shutdown() = 0;
    virtual bool is_alive() = 0;
    virtual bool is_sim() = 0;

protected:
    virtual int keep_alive(int alive) = 0;
    virtual void check_alive() = 0;
};
class RtDev
{
public:
    RtDev(RtDevType type);
    virtual ~RtDev();

    virtual void init();
    virtual int boot_init() = 0;
    void set_master(std::shared_ptr<rtbus::RtCommuItf> master) { master_ = master; }
    bool is_sim() const { return sim_flag_; }
    bool is_alive() const { return alive_flag_; }
    bool is_active() const { return is_active_; }
    void set_watchdog_count(uint32_t count) { COMMU_WATCHDOG_DEFAULT_CNT = count; };
    uint16_t slave_id() const { return slave_id_; }
    virtual void update();
    virtual void action_when_online(){};
    virtual void action_when_offline(){};
    virtual void active() { is_active_ = true; }
    virtual void deactive() { is_active_ = false; }
    void set_master(int busid)
    {
        if (bus_id_ == -1)
        {
            bus_id_ = busid;
        }
    }
    int get_master_id() const { return bus_id_; }

protected:
    int bus_id_;
    RtDevType type_;
    uint16_t slave_id_ = 0;
    bool sim_flag_ = false;
    bool alive_flag_ = false;
    bool is_active_ = true;
    uint32_t alive_watchdog_;  //通讯超时看门狗
    uint32_t COMMU_WATCHDOG_DEFAULT_CNT = 125;
    void check_alive();
    void keep_alive() { alive_watchdog_ = COMMU_WATCHDOG_DEFAULT_CNT; }

protected:
    std::shared_ptr<rtbus::RtCommuItf> master_;
};

class RtDevMgr
{
public:
    static RtDevMgr& instance()
    {
        static RtDevMgr mgr;
        return mgr;
    }
    ~RtDevMgr() {}

    //初始化机柜和手柄，必须成功，若内部失败则会构建一个默认的仿真模式的的机柜和手柄
    int init_cab_bp();

    inline std::shared_ptr<SafetyBoardItf> get_scb() { return scb_; }

private:
    std::shared_ptr<SafetyBoardItf> scb_;
};

void device_update(double ts);

}  // namespace rtdev